package codeflyer.server;

import java.io.IOException;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

import org.apache.log4j.Logger;

import codeFlyer.web.api.Filter;
import codeFlyer.web.api.HttpServlet;
import codeFlyer.web.api.Listener;
import codeflyer.server.classload.ClassLoad;
import codeflyer.server.utils.AnalysisXml;
import codeflyer.server.utils.PropertiesAnalysis;

/**
 * @author CodeFlyer
 * @date May 1, 2020
 * @version 1.0
 */

public class ServerDispatcher implements Runnable{
	private static Logger logger = Logger.getLogger(ServerDispatcher.class);
	
	private Socket socket;
	
	private Map<String, List<HttpServlet>> servletMap = new HashMap<>();  //存储项目的所有servlet对象和路径
	private Map<String, List<Filter>> filterMap = new HashMap<>();   //存储过滤器
	private List<Listener> listenerList = null;    //存储项目的所有listener对象
	private Session session = null;
	private ApplicationContext applicationContext = null;
	private String project = null;
	
	public String getProject() {
		return project;
	}

	public void setProject(String project) {
		this.project = project;
	}

	public ApplicationContext getApplicationContext() {
		return applicationContext;
	}

	public void setApplicationContext(ApplicationContext applicationContext) {
		this.applicationContext = applicationContext;
	}

	public Session getSession() {
		return session;
	}

	public void setSession(Session session) {
		this.session = session;
	}

	public ServerDispatcher(Socket socket) {
		super();
		this.socket = socket;
	}

	public Map<String, List<HttpServlet>> getServletMap() {
		return servletMap;
	}

	public void setServletMap(Map<String, List<HttpServlet>> servletMap) {
		this.servletMap = servletMap;
	}

	public Map<String, List<Filter>> getFilterMap() {
		return filterMap;
	}

	public void setFilterMap(Map<String, List<Filter>> filterMap) {
		this.filterMap = filterMap;
	}

	public List<Listener> getListenerList() {
		return listenerList;
	}

	public void setListenerList(List<Listener> listenerList) {
		this.listenerList = listenerList;
	}

	//输入流必须要等待响应完成时才可以关闭,不然输出会报错
	public void handle(Socket socket) {
		RequestReadByte readByte = new RequestReadByte();
		readByte.setApplicationContext(applicationContext);
		readByte.setSession(session);
		readByte.receive(socket);    //处理完请求
		if(readByte.getIsClose() == true) {
			//表示服务器已断开连接
			System.out.println("************-- 客户端已断开连接 --*************");
		}else {
			//响应处理器,根据具体的请求响应具体的内容
			//1响应图片
			//2响应字符
			//3响应页面
			Response response = new Response();
			response.setProject(project);
			response.setRequest(readByte);
			response.setFilePath(readByte.getFilePath());
			response.setContentType(readByte.getContentType());
			response.setSocket(socket);		
			String httpPath = readByte.getFilePath();
			System.out.println("解析得到的路径---------->"+httpPath);
			
			//在执行拦截器之前应该判断是不是静态资源,是静态资源不会被拦截器拦截
			//只有后缀为.html的静态资源和Servlet的路径会被拦截,/*
			//在此之前还要得到该项目下的所有Servlet路径,然后和httpPath一一进行比较看是否包含
			Set<String> set = servletMap.keySet();
			boolean isExist = set.contains(httpPath);
			//哪些页面被设置了不被拦截,从properties文件中取得路径
			String execludes = PropertiesAnalysis.getPMap().get("exclude");
			String[] execlude = null;
			if(execludes.contains(" ")) {
				//有空格进行分割
				execlude = execludes.split(" ");
			}else {
				execlude = new String[1];
				execlude[0] = execludes;
			}
			
			Chain chain = null;
			if(filterMap.size()>0) {
				for (Entry<String, List<Filter>> entry : filterMap.entrySet()) {
					if(entry.getKey().equals(httpPath)) {
						chain = new Chain(entry.getValue(),readByte,response);
						chain.doChain();
					}else if(entry.getKey().equals("/*")) {
						if(httpPath.endsWith("401.html") || httpPath.endsWith("404.html") || httpPath.endsWith("500.html")) {
							//不执行过滤器
						}else if(httpPath.endsWith(".html")) {
							//从配置文件中设置哪些html页面不被拦截,否则默认拦截所有html页面,设置一个布尔值来判断
							boolean ex = false;
							for (String string : execlude) {
								if(httpPath.endsWith(string)) {
									ex = true;
								}
							}
							if(ex == true) {  //被设置了不被拦截
								
							}else{
								chain = new Chain(entry.getValue(),readByte,response);
								chain.doChain();
							}
						}else if(isExist) {
//							chain = new Chain(entry.getValue(),readByte,response);
//							chain.doChain();
						}else {  //只会拦截servlet和html页面其余静态资源不拦截
							//不执行过滤器
						}						
					}
				}
			}
			//------------------------------fitler执行完毕----------------------------------------
			if( chain == null ) {                  //没有filter对象
				if(servletMap.size()>0) {
					for (Entry<String, List<HttpServlet>> sEntry : servletMap.entrySet()) {
						if(sEntry.getKey().equals(httpPath)) {
							for (HttpServlet s : sEntry.getValue()) {
								s.dopost(readByte, response);
							}
						}else if(sEntry.getKey().equals("/*")) {
							if(sEntry.getKey().endsWith(".html")) {
//								//从配置文件中设置哪些html页面不被拦截,否则默认拦截所有html页面,设置一个布尔值来判断
								boolean ex = false;
								for (String string : execlude) {
									if(httpPath.endsWith(string)) {
										ex = true;
									}
								}
								if(ex == true) {
									response.response();
								}else {
									for (HttpServlet s : sEntry.getValue()) {
										s.dopost(readByte, response);
									}
								}								
							}else {
								response.response();
							}							
						}else {
							response.response();
						}
					}
					if(!response.getSocket().isClosed()) {
						//如果servlet没有进行跳转,那么这请求被拦截,返回一个错误页面
						response.forward("/error/500.html");
					}
				}
			}else {
				if(chain.isExecutor() == true) {
					for (Entry<String, List<HttpServlet>> sEntry : servletMap.entrySet()) {
						if(sEntry.getKey().equals(httpPath)) {
							for (HttpServlet s : sEntry.getValue()) {
								s.dopost(readByte, response);
							}
						}else if(sEntry.getKey().equals("/*")) {
							if(sEntry.getKey().endsWith(".html")) {
								//从配置文件中设置哪些html页面不被拦截,否则默认拦截所有html页面,设置一个布尔值来判断
								boolean ex = false;
								for (String string : execlude) {
									if(httpPath.endsWith(string)) {
										ex = true;
									}
								}
								if(ex == true) {
									response.response();
								}else {
									for (HttpServlet s : sEntry.getValue()) {
										s.dopost(readByte, response);
									}
								}	
							}else {
								response.response();
							}
						}else {
							response.response();
						}
					}
					
					if(!response.getSocket().isClosed()) {
						//如果servlet没有进行跳转,那么这请求被拦截,返回一个错误页面
						response.forward("/error/500.html");
					}				
				}else {
					//判断是已经被转发
					if(!response.getSocket().isClosed()) {
						System.err.println("Chain是否放行成功-------->"+chain.isExecutor());
						response.forward("/error/401.html");     //返回服务器提供的401无访问权限
					}					
				}
			}
			
		}
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		handle(socket);		
		try {
			socket.close(); //接收一个http请求,必须关闭socket,否则无法接受下一个请求
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
		
		System.out.println();
		System.out.println("***********"+Thread.currentThread().getName()+"线程执行完毕**************************");
	}

}


